package com.lin.util;


import lombok.extern.slf4j.Slf4j;
import org.apache.poi.POIXMLDocument;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.io.IOException;
import java.io.InputStream;
import java.io.PushbackInputStream;
import java.util.ArrayList;
import java.util.List;

/**
 * excel导入工具
 *
 * @author 九分石人, 2019-12-31
 */
@Slf4j
public class ExcelImportUtil {

    /**
     * 导入Excel
     *
     * @param fileInputStream 文件输入流
     * @param validColumn     关键列
     * @param startRow        开始行,如第一行就是1
     * @return 数组的集合
     * @author com.lin, 2019-12-19
     */
    @Nullable
    public static List<String[]> readExcelFile(InputStream fileInputStream, int validColumn, int startRow) {
        try {
            Workbook workbook = getWeebWork(fileInputStream);
            // 只取sheet1的数据
            Sheet sheet = workbook.getSheetAt(0);
            return readFromSheet(sheet, validColumn, startRow);
        } catch (Exception e) {
            log.error(e.getMessage());
        } finally {
            if (fileInputStream != null) {
                try {
                    fileInputStream.close(); // 关闭流
                } catch (IOException e) {
                    log.error(e.getMessage());
                }
            }
        }
        return null;
    }


    /**
     * 获取Workbook格式的Excel文件
     *
     * @param inputStream 文件输入流
     * @return Excel文件
     * @throws IOException            文件输入流异常
     * @throws InvalidFormatException 格式校验异常
     * @author com.lin, 2019-12-19
     */
    @NotNull
    @Contract("_ -> new")
    private static Workbook getWeebWork(@NotNull InputStream inputStream) throws IOException, InvalidFormatException {
        if (!inputStream.markSupported()) {
            inputStream = new PushbackInputStream(inputStream, 8);
        }
        if (POIFSFileSystem.hasPOIFSHeader(inputStream)) {
            return new HSSFWorkbook(inputStream);
        }
        if (POIXMLDocument.hasOOXMLHeader(inputStream)) {
            return new XSSFWorkbook(OPCPackage.open(inputStream));
        }
        throw new IllegalArgumentException("你的excel版本目前poi解析不了");
    }


    /**
     * 获取Excel文件中的数据
     *
     * @param sheet       Excel文件中不同的Sheet
     * @param validColumn 关键列，不可为空
     * @param startRow    开始行,如第一行就是1
     * @return 每一列为一个数组，所有元素为数组的集合
     * @author com.lin, 2019-12-19
     */
    @NotNull
    private static List<String[]> readFromSheet(@NotNull Sheet sheet, int validColumn, int startRow) {
        List<String[]> list = new ArrayList<>();
        // 限制不能超过5000条数据
        int maxNum = 5000;
        // 获取总行
        int rowNum = sheet.getLastRowNum();
        // 获取总列数
        int totalCellNum = sheet.getRow(1).getLastCellNum();
        // 设置获取总行数,如果大于5000,则截止为5000.
        if (rowNum >= maxNum) {
            rowNum = 5000;
        }
        // 从第三行开始处理数据
        for (int i = (startRow - 1); i <= rowNum; i++) {
            Row row = sheet.getRow(i);
            if (row != null) {
                // 第X列数据不完整的话 视为无效数据 不予添加进list中
                if (row.getCell(validColumn) == null) {
                    continue;
                }
                try {
                    //设置成文本格式
                    row.getCell(validColumn).setCellType(Cell.CELL_TYPE_STRING);
                } catch (Exception e) {
                    log.error(e.getMessage());
                }
                // 根据标题行生成相同列数的String数组
                String[] cells = new String[totalCellNum];
                for (int j = 0; j < totalCellNum; j++) {
                    Cell cell = row.getCell(j);
                    if (cell != null) {
                        if (!"".equals(String.valueOf(cell).trim())) {
                            // 每个有效数据单元格都转化为String类型
                            cells[j] = String.valueOf(cell).trim();
                        } else {
                            cells[j] = null;
                        }
                    } else {
                        cells[j] = null;
                    }
                }
                list.add(cells);
            }
        }
        return list;
    }


}
